package com.et114.core.control;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.et114.core.common.AppContext;
import com.et114.core.utility.Sentence;
import com.et114.core.utility.ThreadSynchronizer;

/*
 * @author guanhw
 */
public class FileDownloadServlet extends HttpServlet {
	private static final long	serialVersionUID	= 5245384416544736397L;
	private String				path				= "upload";	// 文件目录，默认为upload
	private Log logger = LogFactory.getLog( this.getClass( ) );
	String charSet = AppContext.getFrameWorkPropertiesBean().getCharSet() ;
	public void init ( ) throws ServletException {
		path = this.getInitParameter( "filePath" );// 获取用户配置的文件目录
		if ( path == null )  throw new ServletException( "servlet downloadAction 参数 path 不能为空！" ) ;
	}

	protected void doGet ( HttpServletRequest arg0 , HttpServletResponse arg1 )
			throws ServletException , IOException {
		doPost( arg0, arg1 );
	}

	public void doPost ( HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
		String fileName = request.getParameter( "fileName" );// 文件名称
		if ( fileName != null && !"".equals( fileName.trim() ) ) {
			ThreadSynchronizer.threadEnter();
			fileName = Sentence.replace( fileName , 0 , "/", File.separator , Sentence.IGNORE_CASE ) ;
			fileName = Sentence.replace( fileName , 0 , "\\", File.separator , Sentence.IGNORE_CASE ) ;
			String realname = "";
			try {
				realname =  fileName ;
				if ( realname.indexOf( "/" ) != -1 )
					realname = realname.substring(
							realname.lastIndexOf( "/" ) + 1, realname.length() );
			} catch ( Exception e1 ) {
				logger.error(  e1.getMessage() , e1  ) ;
			}
			
			realname = new String( realname.getBytes( charSet ) , "ISO-8859-1" ) ;
			String realpath = getServletContext().getRealPath( path );// 获取文件目录真实路径
	
			String rpfn = null ; 
			if ( !fileName.startsWith( File.separator ) ) {
				 rpfn = realpath + File.separator + fileName ; 
			}
			else{
				rpfn = realpath + fileName ; 
			}
			File rpfnF = new File( rpfn ) ; 
			if ( !rpfnF .exists() || !rpfnF.canRead() ) {
				throw new ServletException( rpfn + "不存在！" ) ;
			}
			
			response.setContentType( "application/octet-stream-dummy;charset=" + charSet );
			response.setHeader( "Content-Disposition" , "attachment; filename=\"" + realname + "\"" );// 设置response头
			OutputStream os = null;
			InputStream is = null;
			
			try {
				//fileName = Native2Ascii.encode( fileName ) ;
				os = response.getOutputStream();

				is = new FileInputStream( realpath + File.separator + fileName );
				int byteRead;
				byte [ ] buffer = new byte [ 4096 ];
				while ( ( -1 ) != ( byteRead = is.read( buffer ) ) ) {
					os.write( buffer, 0, byteRead );
				}
				os.flush();// 显示文件
			} catch ( Exception e ) {
				logger.error(  e.getMessage() , e  ) ;
			} finally {
				try {
					if ( is != null )
						is.close();
					if ( os != null )
						os.close();
				} catch ( Exception e ) {
					logger.error(  e.getMessage() , e  ) ;
				}
				ThreadSynchronizer.threadExit();
			}
		}
		else {
			 throw new ServletException( "下载文件名不能为空！" ) ;
		}
	}

	/**
	 * 将文件名中的汉字转为UTF8编码的串,以便下载时能正确显示另存的文件名.
	 * 
	 * @param s原文件名
	 * @return 重新编码后的文件名
	 */
	public String toUtf8String ( String s ) {
		StringBuffer sb = new StringBuffer();
		for ( int i = 0; i < s.length(); i++ ) {
			char c = s.charAt( i );
			if ( c >= 0 && c <= 255 ) {
				sb.append( c );
			} else {
				byte [ ] b;
				try {
					b = String.valueOf( c ).getBytes( charSet ); // Character.toString(c).getBytes("utf-8");
				} catch ( Exception ex ) {
					b = new byte [ 0 ];
				}
				for ( int j = 0; j < b.length; j++ ) {
					int k = b [ j ];
					if ( k < 0 )
						k += 256;
					sb.append( "%" + Integer.toHexString( k ).toUpperCase() );
				}
			}
		}
		return sb.toString();
	}

}
